// composables/useDBTableSelector.js
import { ref, watch, computed, h, createApp } from 'vue';
import {
  ElMessage,
  ElDialog,
  ElSelect,
  ElOption,
  ElButton,
  ElForm,
  ElFormItem,
  ElLoading,
} from 'element-plus';
import { smartTranslate as $t } from '@/lang';
import { Check } from '@element-plus/icons-vue';
import API from '@/api/admin/dev/menu';

/**
 * 数据库连接和表选择组合式函数
 * 仅提供一个弹窗方法用于选择数据库连接和表，并将选择结果返回给调用方
 */
export function useDBTableSelector() {
  /**
   * 显示数据库选择弹窗
   * @param {Object} options 弹窗配置选项
   * @param {string} [options.dialogTitle=\'选择数据库和表\'] - 弹窗的标题
   * @param {string} [options.dialogWidth=\'500px\'] - 弹窗的宽度
   * @param {string} [options.defaultConnect] - 默认选中的数据库连接ID或值
   * @param {string} [options.defaultTable] - 默认选中的数据库表名或值
   * @param {string} [options.defaultDirLevel=1] - 默认表名前几层为目录层级
   * @returns {Promise} 返回一个Promise，成功时resolve { connect, table }，失败时reject 'cancel'
   */
  const showDBTableSelectorDialog = (options = {}) => {
    return new Promise((resolve, reject) => {
      let dialogVisible = ref(true);

      // 弹窗内部的状态和方法
      const dialogSelectedConnect = ref(options.defaultConnect || '');
      const dialogSelectedTable = ref(options.defaultTable || '');
      const dialogSelectedDirLevel = ref(options.defaultDirLevel || 1);
      const dialogConnectOptions = ref([]);
      const dialogTableOptions = ref([]);
      const dialogConnectLoading = ref(false);
      const dialogTableLoading = ref(false);
      const dialogSubmitLoading = ref(false);

      const dialogIsFormValid = computed(() => {
        return dialogSelectedConnect.value && dialogSelectedTable.value;
      });

      const dialogFetchConnects = async () => {
        try {
          dialogConnectLoading.value = true;
          const { data } = await API.getConnects();
          dialogConnectOptions.value = data;
          if (options.defaultConnect && dialogConnectOptions.value.length > 0) {
            const defaultOption = dialogConnectOptions.value.find(
              (item) =>
                item.value === options.defaultConnect ||
                item.id === options.defaultConnect,
            );
            if (defaultOption) {
              dialogSelectedConnect.value =
                defaultOption.value || defaultOption.id;
            }
          }
        } catch (error) {
          console.error('获取数据库连接失败:', error);
          ElMessage.error('获取数据库连接失败');
          dialogConnectOptions.value = [];
        } finally {
          dialogConnectLoading.value = false;
        }
      };

      const dialogFetchTables = async (connect) => {
        if (!connect) {
          dialogTableOptions.value = [];
          dialogSelectedTable.value = '';
          return;
        }
        try {
          dialogTableLoading.value = true;
          const { data } = await API.getConnectTables({ connect });
          dialogTableOptions.value = data;
          dialogSelectedTable.value = '';
          if (options.defaultTable && dialogTableOptions.value.length > 0) {
            const defaultOption = dialogTableOptions.value.find(
              (item) =>
                item.value === options.defaultTable ||
                item.id === options.defaultTable,
            );
            if (defaultOption) {
              dialogSelectedTable.value =
                defaultOption.value || defaultOption.id;
            }
          }
        } catch (error) {
          console.error('获取数据库表失败:', error);
          ElMessage.error('获取数据库表失败');
          dialogTableOptions.value = [];
          dialogSelectedTable.value = '';
        } finally {
          dialogTableLoading.value = false;
        }
      };

      watch(
        dialogSelectedConnect,
        (newConnect) => {
          if (newConnect) {
            dialogFetchTables(newConnect);
          } else {
            dialogTableOptions.value = [];
            dialogSelectedTable.value = '';
            dialogSelectedDirLevel.value = 1;
          }
        },
        { immediate: true },
      );

      const handleConfirm = async () => {
        if (!dialogIsFormValid.value) {
          ElMessage.warning('请选择数据库连接和数据表');
          return;
        }

        dialogSubmitLoading.value = true; // 启用提交按钮加载状态
        try {
          const result = {
            connect: dialogSelectedConnect.value,
            table: dialogSelectedTable.value,
            level: dialogSelectedDirLevel.value,
          };
          dialogVisible.value = false;
          resolve(result);
        } catch (error) {
          console.error('确认选择时发生错误:', error);
          ElMessage.error('确认选择时发生错误');
          reject(error);
        } finally {
          dialogSubmitLoading.value = false; // 禁用提交按钮加载状态
        }
      };

      const handleCancel = () => {
        dialogVisible.value = false;
        reject('cancel');
      };

      // 创建对话框组件
      const DBTableSelectorDialog = {
        setup() {
          // 初始化数据
          dialogFetchConnects();

          return () =>
            h(
              ElDialog,
              {
                modelValue: dialogVisible.value,
                'onUpdate:modelValue': (val) => (dialogVisible.value = val),
                title: options.dialogTitle || '选择数据库和表',
                width: options.dialogWidth || '500px',
                'destroy-on-close': true,
                'before-close': handleCancel,
                closeOnClickModal: false,
                closeOnPressEscape: false,
                vLoading:
                  dialogConnectLoading.value || dialogTableLoading.value,
              },
              {
                default: () => [
                  h(
                    ElForm,
                    {
                      labelWidth: '100px',
                      vLoading:
                        dialogConnectLoading.value || dialogTableLoading.value,
                    },
                    () => [
                      h(
                        ElFormItem,
                        { label: $t('common.label.db_conn', '数据库连接') },
                        () =>
                          h(
                            ElSelect,
                            {
                              modelValue: dialogSelectedConnect.value,
                              'onUpdate:modelValue': (val) =>
                                (dialogSelectedConnect.value = val),
                              placeholder: '请选择数据库连接',
                              loading: dialogConnectLoading.value,
                              clearable: true,
                              filterable: true,
                              style: { width: '100%' },
                            },
                            () =>
                              dialogConnectOptions.value.map((item) =>
                                h(ElOption, {
                                  key: item.value || item.id,
                                  label: item.label || item.name,
                                  value: item.value || item.id,
                                }),
                              ),
                          ),
                      ),
                      h(
                        ElFormItem,
                        { label: $t('common.label.db_table', '数据表') },
                        () =>
                          h(
                            ElSelect,
                            {
                              modelValue: dialogSelectedTable.value,
                              'onUpdate:modelValue': (val) =>
                                (dialogSelectedTable.value = val),
                              placeholder: $t(
                                'common.message.placeholder.select',
                                '请选择{label}',
                                {
                                  label: $t(
                                    'common.label.db_conn',
                                    '数据库连接',
                                  ),
                                },
                              ),
                              loading: dialogTableLoading.value,
                              disabled: !dialogSelectedConnect.value,
                              clearable: true,
                              filterable: true,
                              style: { width: '100%' },
                            },
                            () =>
                              dialogTableOptions.value.map((item) =>
                                h(ElOption, {
                                  key: item.value || item.id || item.table_name,
                                  label:
                                    item.label || item.name || item.table_name,
                                  value:
                                    item.value || item.id || item.table_name,
                                }),
                              ),
                          ),
                      ),
                      h(
                        ElFormItem,
                        { label: $t('common.label.dir_level', '目录层级') },
                        () => [
                          h(
                            ElInputNumber,
                            {
                              modelValue: dialogSelectedDirLevel.value,
                              'onUpdate:modelValue': (val) =>
                                (dialogSelectedDirLevel.value = val),
                              placeholder: '请说明表名前几层为目录，默认1层',
                              min: 0,
                              max: 10,
                              style: { width: '100%' },
                            },
                            () => null,
                          ),
                          h(
                            ElText,
                            {
                              tag: 'p',
                              type: 'info',
                              size: 'small',
                              style: { marginTop: '4px' },
                            },
                            () =>
                              '例如：表名demo_from_table,如目录层级为1则第一部分demo为目录,后面剩余部分为文件名，即FromTable;',
                          ),
                          h(
                            ElText,
                            {
                              tag: 'p',
                              type: 'danger',
                              size: 'small',
                              style: { marginTop: '4px' },
                            },
                            () =>
                              '从表生成需要配置表的注释否则无法生成菜单;建议根据表生成菜单后，编辑修改菜单的各个字段，以达到最佳效果。',
                          ),
                        ],
                      ),
                    ],
                  ),
                ],
                footer: () =>
                  h('div', { class: 'dialog-footer' }, [
                    h(
                      ElButton,
                      {
                        onClick: handleCancel,
                      },
                      () => '取消',
                    ),
                    h(
                      ElButton,
                      {
                        type: 'primary',
                        onClick: handleConfirm,
                        loading: dialogSubmitLoading.value,
                        disabled: !dialogIsFormValid.value,
                      },
                      () => [h(Check), ' 确认'], // 按钮文本改为“确认”
                    ),
                  ]),
              },
            );
        },
      };

      // 创建临时挂载点
      const mountPoint = document.createElement('div');
      document.body.appendChild(mountPoint);

      const app = createApp(DBTableSelectorDialog);
      app.use(ElLoading).mount(mountPoint); // Use ElLoading plugin

      // 清理函数
      const cleanup = () => {
        try {
          if (app) {
            app.unmount();
          }
          if (document.body.contains(mountPoint)) {
            document.body.removeChild(mountPoint);
          }
        } catch (e) {
          console.warn('清理对话框时出错:', e);
        }
      };

      // 在resolve或reject后清理
      const originalResolve = resolve;
      const originalReject = reject;
      resolve = (value) => {
        cleanup();
        originalResolve(value);
      };
      reject = (reason) => {
        cleanup();
        originalReject(reason);
      };

      // 监听dialogVisible变化，当弹窗关闭时执行清理
      watch(dialogVisible, (newVal) => {
        if (!newVal) {
          cleanup();
        }
      });
    });
  };

  return {
    showDBTableSelectorDialog,
  };
}
